const { DataTypes, Op } = require('sequelize')
const sequelize = require('../config/database')
const logger = require('../utils/logger')

const Department = sequelize.define('Department', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
    comment: '部门ID'
  },
  name: {
    type: DataTypes.STRING(50),
    allowNull: false,
    comment: '部门名称'
  },
  name_en: {
    type: DataTypes.STRING(50),
    allowNull: true,
    comment: '部门英文名称'
  },
  code: {
    type: DataTypes.STRING(50),
    allowNull: false,
    unique: true,
    comment: '部门编码'
  },
  parent_id: {
    type: DataTypes.INTEGER,
    allowNull: true,
    comment: '父部门ID'
  },
  order_num: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 1,
    comment: '显示顺序'
  },
  leader: {
    type: DataTypes.STRING(50),
    allowNull: true,
    comment: '负责人'
  },
  phone: {
    type: DataTypes.STRING(20),
    allowNull: true,
    comment: '联系电话'
  },
  email: {
    type: DataTypes.STRING(50),
    allowNull: true,
    comment: '邮箱'
  },
  status: {
    type: DataTypes.TINYINT,
    allowNull: false,
    defaultValue: 1,
    comment: '部门状态（1正常 0停用）'
  },
  template_id: {
    type: DataTypes.INTEGER,
    allowNull: true,
    comment: '权限模板ID'
  },
  rules: {
    type: DataTypes.TEXT,
    allowNull: true,
    comment: '特殊权限规则（JSON格式）'
  },
  level: {
    type: DataTypes.INTEGER,
    allowNull: false,
    defaultValue: 1,
    comment: '部门层级'
  }
}, {
  tableName: 'departments',
  timestamps: true,
  paranoid: true,
  indexes: [
    {
      unique: true,
      fields: ['code']
    },
    {
      fields: ['parent_id']
    },
    {
      fields: ['template_id']
    }
  ]
})

// 延迟设置关联关系，避免循环依赖
setTimeout(() => {
  // 自关联关系
  Department.hasMany(Department, {
    as: 'children',
    foreignKey: 'parent_id'
  })
  Department.belongsTo(Department, {
    as: 'parentDepartment',
    foreignKey: 'parent_id'
  })

  // 部门-用户多对多关联
  const User = require('./user')
  const UserDepartment = require('./userDepartment')
  Department.belongsToMany(User, {
    through: UserDepartment,
    foreignKey: 'department_id',
    otherKey: 'user_id',
    as: 'users'
  })

  // 部门-权限模板关联
  const PermissionTemplate = require('./PermissionTemplate')
  Department.belongsTo(PermissionTemplate, {
    foreignKey: 'template_id',
    as: 'permissionTemplate'
  })
}, 0)

// 创建初始根部门
Department.createRootDepartment = async () => {
  try {
    // 检查根部门是否已存在
    const existingRoot = await Department.findOne({
      where: { code: 'ROOT' }
    })

    if (existingRoot) {
      logger.info('根部门已存在，跳过创建')
      return existingRoot
    }

    // 获取普通用户模板
    const PermissionTemplate = require('./PermissionTemplate')
    const normalTemplate = await PermissionTemplate.findOne({
      where: { code: 'normal_user_template' }
    })

    if (!normalTemplate) {
      throw new Error('未找到普通用户权限模板')
    }

    // 创建根部门并设置普通用户模板
    const rootDepartment = await Department.create({
      name: 'XX公司',
      name_en: 'XX Company',
      code: 'ROOT',
      level: 1,
      parent_id: null,
      order_num: 1,
      status: 1,
      template_id: normalTemplate.id,
      rules: JSON.stringify(normalTemplate.permissions)  // 使用模板的默认权限
    })

    logger.info('根部门创建成功')
    return rootDepartment
  } catch (error) {
    logger.error('Create root department error:', error)
    throw error
  }
}

// 生成部门编码
Department.generateCode = async (parentId) => {
  try {
    // 获取父部门
    const parent = parentId ? await Department.findByPk(parentId) : null
    
    // 如果是根部门的子部门，使用 DEPT 前缀
    if (parent && parent.code === 'ROOT') {
      const maxCode = await Department.max('code', {
        where: {
          parent_id: parentId,
          code: { [Op.like]: 'DEPT-%' }
        }
      })
      
      if (!maxCode) return 'DEPT-001'
      
      const num = parseInt(maxCode.split('-')[1]) + 1
      return `DEPT-${String(num).padStart(3, '0')}`
    }
    
    // 其他部门使用父部门编码作为前缀
    const prefix = parent ? parent.code : 'DEPT'
    const maxCode = await Department.max('code', {
      where: {
        parent_id: parentId,
        code: { [Op.like]: `${prefix}-%` }
      }
    })
    
    if (!maxCode) return `${prefix}-001`
    
    const num = parseInt(maxCode.split('-')[1]) + 1
    return `${prefix}-${String(num).padStart(3, '0')}`
  } catch (error) {
    logger.error('Generate department code error:', error)
    throw new Error('生成部门编码失败')
  }
}

// 部门状态变更时的钩子函数
Department.afterUpdate(async (department, options) => {
  if (department.changed('status')) {
    const User = require('./user')
    const Role = require('./role')
    const UserDepartment = require('./userDepartment')
    const { LogService } = require('../services/logService')

    const transaction = options.transaction || await sequelize.transaction()

    try {
      // 如果部门被禁用，需要处理该部门的管理员
      if (department.status === 0) {
        // 查找该部门的所有部门管理员
        const deptAdmins = await User.findAll({
          include: [
            {
              model: Role,
              as: 'role',
              where: { code: 'dept_admin' }
            },
            {
              model: Department,
              as: 'departments',
              through: {
                where: { 
                  department_id: department.id,
                  is_primary: true
                }
              }
            }
          ],
          transaction
        })

        // 将这些用户角色改为普通用户
        const normalRole = await Role.findOne({
          where: { code: 'normal_user' },
          transaction
        })

        const affectedUsers = []
        for (const admin of deptAdmins) {
          if (normalRole) {
            const previousRole = admin.role
            await admin.update({ role_id: normalRole.id }, { 
              transaction,
              operatorId: options.operatorId,
              ip: options.ip,
              remark: `因部门 ${department.id} 停用而自动调整角色`
            })
            affectedUsers.push({
              id: admin.id,
              previousRole,
              currentRole: normalRole
            })
          }
        }

        // 记录部门状态变更日志
        await LogService.logDepartmentStatusChange({
          department_id: department.id,
          operator_id: options.operatorId,
          before: department._previousDataValues.status,
          after: department.status,
          affected_users: affectedUsers,
          remark: options.remark || '部门状态变更',
          ip: options.ip || '127.0.0.1',
          transaction
        })
      }

      if (!options.transaction) {
        await transaction.commit()
      }
    } catch (error) {
      if (!options.transaction) {
        await transaction.rollback()
      }
      logger.error('Process department status change error:', error)
      throw error
    }
  }
})

module.exports = Department 